wayland: use memfd_create instead of open in tmpdir
authorRay Strode <rstrode@redhat.com>
Mon, 25 Jan 2016 16:41:23 +0000 (11:41 -0500)
committerRay Strode <rstrode@redhat.com>
Mon, 25 Jan 2016 18:36:23 +0000 (13:36 -0500)
The tmpdir is used for a wide assortment of things, and
can easily fill up. If it fills then desktop will start
crashing with SIGBUS errors.

This commit changes the shm pool allocation code, to use
memfd_create, instead, so the shared memory files will
be anonymous and not associated with /tmp

https://bugzilla.gnome.org/show_bug.cgi?id=761095

gdk/wayland/gdkdisplay-wayland.c

index 5e88d966ad612949a47bd6ac28e21f0b8209330c..360c4898055c7a9cf016b201dbe2e520cf3b0a5c 100644 (file)
@@ -22,7 +22,9 @@
 #include <errno.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <linux/memfd.h>
 #include <sys/mman.h>
+#include <sys/syscall.h>
 
 #include <glib.h>
 #include "gdkwayland.h"
@@ -928,27 +930,24 @@ create_shm_pool (struct wl_shm  *shm,
                  size_t         *buf_length,
                  void          **data_out)
 {
-  char *filename;
   struct wl_shm_pool *pool;
-  int fd;
+  int ret, fd;
   void *data;
 
-  filename = g_strconcat (g_get_tmp_dir (), G_DIR_SEPARATOR_S, "wayland-shm-XXXXXX", NULL);
-  fd = mkstemp (filename);
-  if (fd < 0)
+  ret = syscall (SYS_memfd_create, "gdk-wayland", MFD_CLOEXEC);
+
+  if (ret < 0)
     {
-      g_critical (G_STRLOC ": Unable to create temporary file (%s): %s",
-                  filename, g_strerror (errno));
-      g_free (filename);
+      g_critical (G_STRLOC ": creating shared memory file failed: %s",
+                  g_strerror (-ret));
       return NULL;
     }
-  unlink (filename);
+
+  fd = ret;
 
   if (ftruncate (fd, size) < 0)
     {
-      g_critical (G_STRLOC ": Truncating temporary file (%s) failed: %s",
-                  filename, g_strerror (errno));
-      g_free (filename);
+      g_critical (G_STRLOC ": Truncating shared memory file failed: %m");
       close (fd);
       return NULL;
     }
@@ -957,9 +956,7 @@ create_shm_pool (struct wl_shm  *shm,
 
   if (data == MAP_FAILED)
     {
-      g_critical (G_STRLOC ": mmap'ping temporary file (%s) failed: %s",
-                  filename, g_strerror (errno));
-      g_free (filename);
+      g_critical (G_STRLOC ": mmap'ping shared memory file failed: %m");
       close (fd);
       return NULL;
     }
@@ -967,7 +964,6 @@ create_shm_pool (struct wl_shm  *shm,
   pool = wl_shm_create_pool (shm, fd, size);
 
   close (fd);
-  g_free (filename);
 
   *data_out = data;
   *buf_length = size;